import { Injectable, UseFilters } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import { InjectRepository } from '@nestjs/typeorm';
import { HttpExceptionFilter } from 'src/common/http-exception.filter';
import { getPagination, throwHttp } from 'src/utlis';
import { Between, Like, Repository } from 'typeorm';
import {
  RegisterUserDto,
  ValidateUserDto,
  UpdatePassWordDto,
  GetUserInfoDto,
  AdminUserBindRoleDto,
  GetAdminUserPage,
  UpdateAdminUserDto,
  DelteIdDto,
} from './dto/admin-user.dto';
import { AdminUser } from './entities/admin-user.entity';
import { compareSync, hashSync } from 'bcryptjs';
import { isNil, isEmpty, equals } from 'ramda';
import { IdDto } from 'src/common/dto/dto';
import { isTrue } from 'src/utlis/tools';
import { RoleService } from 'src/modules/role/role.service';
@Injectable()
export class AdminUserService {
  constructor(
    @InjectRepository(AdminUser)
    private readonly adminUserRepository: Repository<AdminUser>,
    private readonly roleService: RoleService,
    private readonly jwtService: JwtService,
  ) { }
  async getAdminUserPage(params: GetAdminUserPage) {
    try {
      const {
        createTimeStart,
        createTimeEnd,
        updateTimeEnd,
        updateTimeStart,
        username,
        account,
        isDel,
        id,
      } = params;
      const { pageSize, pageNum } = getPagination({
        pageSize: params.pageSize,
        pageNum: params.pageNum,
      });
      const where: GetAdminUserPage = {
        username: Like(`%${username || ''}%`),
        account: Like(`%${account || ''}%`),
        isDel,
        id,
      };
      // 创建时间筛选
      if (!isNil(createTimeStart) && !isNil(createTimeEnd)) {
        where.createDate = Between(createTimeStart, createTimeEnd);
      }
      // 更新时间筛选
      if (!isNil(updateTimeStart) && !isNil(updateTimeEnd)) {
        where.updateDate = Between(updateTimeStart, updateTimeEnd);
      }
      const [data, total] = await this.adminUserRepository.findAndCount({
        where,
        cache: true,
        skip: pageNum * pageSize,
        take: pageSize,
        order: { createDate: 'DESC' },
        relations: ['roles']
      });
      return {
        data,
        total,
        pageSize,
        pageNum: pageNum * pageSize + 1,
      };
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 登录 */
  @UseFilters(new HttpExceptionFilter())
  async login(params: ValidateUserDto) {
    const { username, password } = params;
    const user = await this.adminUserRepository.findOne({
      where: { account: username },
      select: ['username', 'password', 'id'],
      relations: ['roles'],
    });
    if (!user) {
      throwHttp('用户不存在');
    }
    if (!compareSync(password, user.password)) {
      throwHttp('用户名或密码不正确');
    }
    if (equals(Number(user.isDel), 0)) {
      throwHttp('账号已被禁用');
      return
    }
    const payload = {
      username: user.username,
      userId: user.id,
      roles: user.roles,
    };
    // 把信息存在token
    return {
      token: this.jwtService.sign(payload),
      id: user.id,
    };
  }
  // 注册
  @UseFilters(new HttpExceptionFilter())
  async registerAdminUser(params: RegisterUserDto): Promise<string> {
    try {
      const { username, password, isDel, avatar, account } = params;
      const userInfo = await this.adminUserRepository.findOne({
        where: { username },
      });
      if (!isNil(userInfo)) {
        throwHttp('用户已存在');
      }
      const user = new AdminUser();
      user.username = username;
      user.account = account;
      user.password = password;
      user.isDel = isDel;
      user.avatar = avatar;
      const result = await this.adminUserRepository.manager.save(user);
      if (!isEmpty(result)) {
        return `注册成功`;
      }
      throwHttp('注册失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 修改密码 */
  @UseFilters(new HttpExceptionFilter())
  async updatePassWord(params: UpdatePassWordDto) {
    try {
      const { userId, old_password, new_password } = params;
      const userInfo = await this.adminUserRepository.findOne({
        where: { id: userId },
        select: ['password'],
      });
      if (isNil(userInfo)) {
        throwHttp('用户不存在');
        return;
      }
      if (!compareSync(old_password, userInfo.password)) {
        throwHttp('登录密码不正确');
      }
      if (equals(Number(userInfo.isDel), 0)) {
        throwHttp('账号已被禁用');
        return
      }
      const { affected } = await this.adminUserRepository
        .createQueryBuilder()
        .update(AdminUser)
        .set({
          password: await hashSync(new_password),
        })
        .where('id = :id', { id: userId })
        .execute();
      if (affected) {
        return '密码修改成功';
      }
      throwHttp('密码修改失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 重置密码 */
  @UseFilters(new HttpExceptionFilter())
  async resetPassWord(body: DelteIdDto) {
    try {
      const { id } = body;
      const userInfo = await this.adminUserRepository.findOne({
        where: { id },
        select: ['password'],
      });
      if (isNil(userInfo)) {
        throwHttp('用户不存在');
        return;
      }
      const { affected } = await this.adminUserRepository
        .createQueryBuilder()
        .update(AdminUser)
        .set({
          password: await hashSync('123456'),
        })
        .where('id = :id', { id })
        .execute();
      if (affected) {
        return '密码重置成功';
      }
      throwHttp('密码重置失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 获取用户权限 */
  async getUserRolePermissions(userId: number) {
    try {
      const data = await this.adminUserRepository.findOne({
        where: { id: userId },
      });
      return data.roles;
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 删除用户 */
  @UseFilters(new HttpExceptionFilter())
  async delAdminUser({ id }: IdDto) {
    try {
      await this.getUserInfo({ id });
      const { affected } = await this.adminUserRepository
        .createQueryBuilder()
        .update('Admin_user')
        .set({ del: 0 })
        .where('id = :id', { id })
        .execute();
      if (affected) {
        return '删除成功';
      }
      throwHttp('删除失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 获取用户信息 */
  @UseFilters(new HttpExceptionFilter())
  async getUserInfo(params: GetUserInfoDto): Promise<AdminUser> {
    try {
      const { id, account } = params;
      if (!id && !account) {
        throwHttp('参数为空');
      }
      const data = await this.adminUserRepository.findOne({
        where: { id, account },
        select: ['id', 'account', 'createDate', 'username', 'avatar', 'isDel'],
        relations: ['roles'],
      });
      console.log(data);
      if (equals(Number(data.isDel), 0)) {
        throwHttp('账号已被禁用');
        return
      }
      if (isNil(data)) {
        throwHttp('用户不存在');
        return;
      }
      return data;
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 获取角色信息 */
  @UseFilters(new HttpExceptionFilter())
  async getUserRole(headers) {
    try {
      const token = headers.authorization.split(' ');
      if (!isTrue(token)) {
        throwHttp('获取token失败');
      }
      const user: any = this.jwtService.decode(token[1]);
      const data = await this.adminUserRepository.findOne({
        where: {
          id: user.userId,
        },
        relations: ['roles'],
      });
      if (equals(Number(data.isDel), 0)) {
        throwHttp('账号已被禁用');
        return
      }
      if (isTrue(data.roles?.menu)) {
        data.roles.menu = JSON.parse(data.roles.menu);
      }
      return data
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 绑定用户信息 */
  @UseFilters(new HttpExceptionFilter())
  async adminUserBindRole(body: AdminUserBindRoleDto) {
    try {
      const { userId, roleId } = body;
      const roleInfo = await this.roleService.getRoleInfo({ id: roleId });
      if (isNil(roleInfo)) {
        throwHttp('角色不存在');
        return;
      }
      const user = await this.adminUserRepository.findOne({
        where: { id: userId },
      });
      if (isNil(user)) {
        throwHttp('用户不存在');
        return;
      }
      user.rolesId = roleInfo.id
      user.roles = roleInfo
      const result = await this.adminUserRepository.manager.save(user);
      if (!isEmpty(result)) {
        return `角色绑定成功`;
      }
      throwHttp('角色绑定失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }
  /** 绑定用户信息 */
  @UseFilters(new HttpExceptionFilter())
  async updateAdminUser(body: UpdateAdminUserDto) {
    try {
      const { userId, username, avatar, isDel } = body;
      const userInfo = await this.adminUserRepository.findOne({
        where: { id: userId },
        select: ['id'],
      });
      if (isNil(userInfo)) {
        throwHttp('用户不存在');
        return;
      }
      const { affected } = await this.adminUserRepository
        .createQueryBuilder()
        .update(AdminUser)
        .set({
          username, avatar, isDel,
        })
        .where('id = :id', { id: userId })
        .execute();
      if (affected) {
        return '密码修改成功';
      }
      throwHttp('密码修改失败');
    } catch (error) {
      throwHttp(error.message);
    }
  }

  async addUserIfNotExists() {
    const user = await this.adminUserRepository.findOne({
      where: { account: 'admin' },
      select: ['id', 'account', 'createDate', 'username', 'avatar'],
    });
    if (user) return user
    // 默认注册用户
    await this.registerAdminUser({
      username: 'admin',
      account: 'admin',
      password: 'admin',
      isDel: '1',
      avatar: ''
    })
    return await this.adminUserRepository.findOne({
      where: { account: 'admin' },
      select: ['id', 'account', 'createDate', 'username', 'avatar'],
    });
  }
}
